using M13.Base;
using M13.Game.Entity.FSM;
using M13.Game.Item;
using M13.GameSystem;
using QFramework;
using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using UnityEngine;

namespace M13.Game.Entity.Player
{
    public class PlayerStateMachine : StateMachine, IController
    {
        List<PlayerStateBase> _states = new List<PlayerStateBase>();

        private Animator _animator;
        private IInputCtrlSystem _inputCtrlSystem;
        private ICameraModal _cameraModal;
        private IPlayerModal _playerModal;
        private PlayerEntity _playerEntity;
        private PlayerInventory _playerInventory;

        private void Start()
        {
            stateTable = new Dictionary<Type, IState>(_states.Count);
            _inputCtrlSystem = this.GetSystem<IInputCtrlSystem>();
            
            _animator = GetComponent<Animator>();
            _playerEntity = GetComponent<PlayerEntity>();
            _cameraModal = this.GetModel<ICameraModal>();
            _playerModal = this.GetModel<IPlayerModal>();
            _playerInventory = GetComponent<PlayerInventory>();
            
            _states.Add(new PlayerStateIdle("PlayerStateIdle"));
            _states.Add(new PlayerStateMove("PlayerStateMove"));
            _states.Add(new PlayerActionAttack("PlayerActionAttack"));
            _states.Add(new PlayerActionEatup("PlayerActionEatup"));
            
            
            foreach (var t in _states)
            {
                t.Init(this, _animator, _inputCtrlSystem, _cameraModal, _playerModal, _playerEntity, _playerInventory);
                stateTable.Add(t.GetType(), t);
            }


            SwitchState(typeof(PlayerStateIdle));

            
        }

        private void Update()
        {
            currentState.Update();
        }
        
        public void SwitchOnAction()
        {
            if (_playerInventory.CurrentHeldEmpty()) return;
            ItemType itemType = _playerInventory.GetItemProperties().ItemType;
            switch ((int)itemType)
            {
                case 0:
                {
                    break;
                }
                case 1:
                {
                    SwitchState(typeof(PlayerActionAttack));
                    break;
                }
                case 2:
                {
                    SwitchState(typeof(PlayerActionEatup));
                    break;
                }
            }
        }

        public void SwitchOnState()
        {
            SwitchOnSeveralState(typeof(PlayerStateIdle), typeof(PlayerStateMove));
        }
        
        bool _stateLock = false;
        public async void WhenCompleteProgress(Action action)
        {
            if(_stateLock) return;
            _stateLock = true;
            await UniTask.WhenAll(currentState.GetAnimPlayTask());
            action.Invoke();
            _stateLock = false;
        }

        public bool IsCurrentStateComingToExit()
        {
            return currentState.GetAnimPlayProgress() > 0.99f;
        }

        public bool IsCurrentState(Type stateType)
        {
            return stateTable[stateType] == currentState;
        }

        private void FixedUpdate()
        {
            currentState.FixedUpdate();
        }

        private void OnDrawGizmos()
        {
            if (Application.isPlaying)
                currentState.OnDrawGizmos();
        }

        public IArchitecture GetArchitecture()
        {
            return GameArchitecture.Interface;
        }
    }
}